/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package criptografia;

import java.io.*;
import java.lang.*;
import java.math.BigInteger;

/**
 *
 * @author tata
 */
public class Criptografia {

    /**
     * @param args the command line arguments
     *
     *
     */
    private static char alfab[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
    private static char alfabñ[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z','ñ'};
    private static char especiales[] = {'á', 'à', 'ä', 'é', 'è', 'ë', 'í', 'ì', 'ï', 'ó', 'ò', 'ö', 'ú', 'ù', 'ü', 'ñ'};
    
    public static void main(String[] args) {
        // TODO code application logic here
        String f = "QS.txt";
        String f2 = "cantidad_apariciones.txt";
        double cant[] = new double[27];
        char let[] = new char[27];

        //Creamos la tabla de ocurrencias.
        Apariciones(f, f2, cant, let);//Saco la cantidad de ocurrencias

        //encriptar_shift("pruebajcesar.txt", 26);

    }
    
    public static int bsearch(char a) {
        //primero veo si es un caracter especial
        int posicion = cespeciales(a);
        if (posicion == -1)   {
            posicion = binary(a, 0, 25);
        }
        return posicion;
    }
    
    private static int binary(char a, int pos_ini, int pos_fin) {
        if (pos_fin - pos_ini == 1) {
            if (alfab[pos_ini] == a){ 
                return pos_ini;
            }else if (alfab[pos_fin] == a) {
                return pos_fin;
            }else{return -1;}
        } else if (pos_fin - pos_ini > 0) {
            int pos_mid = ((pos_fin - pos_ini) / 2) + pos_ini;
            if (alfab[pos_mid] > a) {
                return binary(a, pos_ini, pos_mid);
            } else if (alfab[pos_mid] < a) {
                return binary(a, pos_mid, pos_fin);
            } else {
                return pos_mid;
            }
        } else {
            return -1;
        }
    }
    
    public static int cespeciales(char a) {
        int posicion = -1;
        for (int s = 0; s < especiales.length; s++) {
            if (a == especiales[s]) {
                if (s < 3) {//es una A
                    posicion = 0;
                } else if (s < 6) {//es una E
                    posicion = 4;
                } else if (s < 9) { //es una I
                    posicion = 8;
                } else if (s < 12) { //es una O
                    posicion = 14;
                } else if (s < 15) { // es una U
                    posicion = 20;
                } else {  //es una ñ
                    posicion = 26;
                }
            }
        }
        return posicion;
    }
    
    public static void Apariciones(String file1, String file_out, double[] cant, char[] let) {
        double apariciones[] = new double[27];
        int enie = 0;
        
        FileInputStream archivo = null;
        InputStreamReader fr = null;
        BufferedReader br = null;
        
        try {
            // Apertura del fichero y creacion de BufferedReader para poder
            // hacer una lectura comoda (disponer del metodo readLine()).
            archivo = new FileInputStream(file1);
            fr = new InputStreamReader(archivo, "ISO-8859-1");
            br = new BufferedReader(fr);

            // Lectura del fichero
            String linea;
            
            int longitud = 0;
            
            while ((linea = br.readLine()) != null) {
                linea = linea.toLowerCase();                
                for (int l = 0; l < linea.length(); l++) {
                    //comparo las letras, pasarlo a un case.
                    int posicion = bsearch(linea.charAt(l));
                    if (posicion != -1) {
                        apariciones[posicion]++;
                        longitud++;
                   }
                    
                }
                
            }//endwhile

            double longitud2 = 0;
            insertionsort(alfabñ, apariciones, let, cant);
            for (int m = 0; m < 27; m++) {
                //    apariciones[m] = apariciones[m] / longitud;
                longitud2 = longitud2 + cant[m];
                
            }
            
            try {

                //Creamos un Nuevo objeto FileWriter dandole
                //como parámetros la ruta y nombre del fichero
                FileWriter fichero = new FileWriter(file_out);
                
                
                for (int index = 0; index < let.length; index++) {
                    //escribimos el fichero8

                    String total = new Double(cant[index] / longitud).toString();
                    
                    fichero.write(let[index] + " - " + cant[index] + ", " + total + "\r\n");
                    
                }

                //Integer in = new Integer(lontiud)

                fichero.write(" " + longitud + "\r\n");

                //cerramos el fichero
                fichero.close();
                
                
            } catch (Exception ex) {
                ex.printStackTrace();
            }
             
            
        }//endtry         
        catch (Exception e) {
            e.printStackTrace();
        } finally {
            // En el finally cerramos el fichero, para asegurarnos
            // que se cierra tanto si todo va bien como si salta 
            // una excepcion.
            try {
                if (null != fr) {
                    fr.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        
        
    }
    
    public static void insertionsort(char[] letras, double[] apariciones, char[] lsort, double[] asort) {
        int l = 0;
        while (l < apariciones.length) {
            int index_max = 0;
            for (int i = 0; i < apariciones.length; i++) {
                if (apariciones[i] > apariciones[index_max]) {
                    index_max = i;
                }
            }//endfor
            asort[l] = apariciones[index_max];
            lsort[l] = letras[index_max];
            apariciones[index_max] = -1;
            l++;
        }//endwhile

    }//end sort

    public static void encriptar_shift(String file, int numero) {
        File archivo = null;
        FileReader fr = null;
        BufferedReader br = null;
        String nombre = "encriptado_" + numero + ".txt";
        try {
            // Apertura del fichero y creacion de BufferedReader para poder
            // hacer una lectura comoda (disponer del metodo readLine()).
            archivo = new File(file);
            fr = new FileReader(archivo);
            br = new BufferedReader(fr);

            // Lectura del fichero
            String linea;
            //Creamos el nombre de nuestro fichero
            try {
                //Creamos un Nuevo objeto FileWriter dandole
                //como parámetros la ruta y nombre del fichero
                FileWriter fichero = new FileWriter(nombre);
                //RECORRO EL TEXTO
                while ((linea = br.readLine()) != null) {
                    String linea2 = "";
                    for (int i = 0; i < linea.length(); i++) {
                        /*
                         * int l = 0; for (int m = 0; m < alfab.length; m++) {
                         * if (linea.charAt(i) == alfab[m]) { l = m; } } l = l +
                         * numero; l = moduloalfab(l); char letra = alfab[l];
                         *
                         */
                        char letra = shift(linea.charAt(i), numero);
                        linea2 = linea2 + letra;
                    }
                    fichero.write(linea2 + "\r\n");
                }
                //cerramos el fichero
                fichero.close();
                fr.close();
            } catch (Exception ex) {
            }
        } catch (Exception e) {
        }
    }
    
    public static char shift(char letra, int n) {
        int l = 0;
        
        for (int m = 0; m < alfab.length; m++) {
            if (letra == alfab[m]) {
                l = m;
            }
        }
        l = l + n;
        l = moduloalfab(l);
        return alfab[l];
        
    }
    
    public static int moduloalfab(int l) {
        while (l >= 27 && l >= 0) {
            l = l - 27;
        }
        return l;
    }
    
    public static void fuerzabruta_shift(String file) {
        
        File archivo = null;
        FileReader fr = null;
        BufferedReader br = null;
        String nombre = "fbruta_" + ".txt";
        try {
            // Apertura del fichero y creacion de BufferedReader para poder
            // hacer una lectura comoda (disponer del metodo readLine()).

            archivo = new File(file);
            fr = new FileReader(archivo);
            br = new BufferedReader(fr);

            // Lectura del fichero
            String linea;
            //Creamos el nombre de nuestro fichero
            FileWriter fichero = new FileWriter(nombre);
            
            try {
                
                while ((linea = br.readLine()) != null) {
                    for (int i = 0; i < 28; i++) {
                        for (int m = 0; m < linea.length(); m++) {
                            /*
                             * l = l + numero; l = modulo28(l); char letra =
                             * alfab[l]; linea2 = linea2 + letra;
                             */
                        }
                    }
                }
                
            } catch (Exception ex) {
            }
            
        } catch (Exception ex2) {
        }
        
    }
    
    public static void vigenere(String file1, int[] clave) {
        if (clave.length > 0) { //si la clave es vacia no hago nada.

            FileInputStream archivo = null;
            InputStreamReader fr = null;
            BufferedReader br = null;
            try {
                archivo = new FileInputStream(file1); //leo archivo
                fr = new InputStreamReader(archivo, "ISO-8859-1"); //veo el formato para manejar caracteres especiales
                br = new BufferedReader(fr); //meto al buffer
                String linea;
                while ((linea = br.readLine()) != null) { //agarro cada linea
                    linea = linea.toLowerCase();
                    for (int ch = 0; ch < linea.length(); ch++) {
                        int pos_cl = 0;
                        String nueva_linea = "";
                        if (pos_cl >= clave.length) { // si termine de leer el bloque a cifrar empiezo de nuevo el bloque
                            pos_cl = 0;
                        }
                        for (int index = 0; index < alfab.length; index++) { //busco a ver que letra es
                            if (linea.charAt(ch) == alfab[index]) {
                                int nueva_letra = index + clave[pos_cl]; //nueva letra = posicion letra actual + clave_vigenere[i]
                                char letra = alfab[nueva_letra]; //Busco nueva letra
                                nueva_linea = nueva_linea + letra; //guardo mi encriptado
                                pos_cl++; //paso a la clave q viene
                            }
                        } // si no encontro la letra
                        for (int index_esp = 0; index_esp < especiales.length; index_esp++) {
                        }
                        
                        
                    } //end for chars -> linea

                }//end while linea = br.readline

                
            } catch (Exception ex) {
            }
        }//endif

        
    }
}
